package com.haruhi.bot.endpoint.ws.client;

import com.haruhi.bot.endpoint.ws.config.EndpointConfiguration;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.websocket.ClientEndpointConfig;
import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;

@Slf4j
@Component
public class ClientEndpointsManager {

    private final List<EndpointConfiguration.Client> clients;

    private final Map<String, ClientEndpoint> clientContainer = new ConcurrentHashMap<>();
    private final AtomicBoolean started = new AtomicBoolean(false);

    public ClientEndpointsManager(EndpointConfiguration botServersConfiguration) {
        this.clients = botServersConfiguration.getClients();
    }

    @PostConstruct
    private void postConstruct(){
        start();
    }

    private void start(){
        synchronized(ClientEndpointsManager.class){
            if(!started.get()){
                started.set(true);

                for (EndpointConfiguration.Client client : clients) {
                    addClient(client.getUri(),client.getHttpHeaders(),client.getReconnectPeriod());
                }

                for (ClientEndpoint client : clientContainer.values()) {
                    new Thread(()->{
                        if (!client.connect()) {
                            client.reConnect();
                        }
                    }).start();
                }
            }
        }
    }

    public void addClient(URI uri,HttpHeaders httpHeaders,long reconnectPeriod){
        ClientEndpoint client = new ClientEndpoint(uri,ClientEndpointConfig.Builder.create().configurator(new ClientEndpointConfig.Configurator(){
            @Override
            public void beforeRequest(Map<String, List<String>> headers) {
                headers.putAll(httpHeaders);
            }
        }).build(),reconnectPeriod);
        clientContainer.put(uri.toString(),client);
    }

    public void removeClient(String uri){
        ClientEndpoint clientEndpoint = clientContainer.get(uri);
        if (clientEndpoint != null) {
            clientEndpoint.close();
            clientContainer.remove(uri);
        }
    }


}
